/*
 * Copyright 2005-2013 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * Project website:
 *      http://www.cottsoft.com
 */
package com.cottsoft.framework.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.cottsoft.framework.common.flg.EDirection;
import com.cottsoft.framework.common.flg.IFlg;

/**
 * Class Description: <br> 
 * 日期、时间工具类
 * @author  Simon.Hoo(simon@cottsoft.com)
 * @date    2008年6月15日
 * @version v1.0
 * @since   1.0
 */
public class DateUtils implements IFlg{
	public static final String TYPE_yyyyMMdd = "yyyyMMdd";
	public static final String TYPE_yyyyMMddHH = "yyyyMMddHH";
	public static final String TYPE_yyyyMMddHHmm = "yyyyMMddHHmm";
	public static final String TYPE_yyyyMMddHHmmss = "yyyyMMddHHmmss";
	public static final String TYPE_yyyyMMdd_HHmmss = "yyyyMMdd HHmmss";
	public static final String TYPE_yyyy_MM_dd = "yyyy-MM-dd";
	public static final String TYPE_yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
	public static final String TYPE_yyyy_MM_dd_HH_mm_ss_SSS = "yyyy-MM-dd HH:mm:ss,SSS";
	
	/**
	 * Description: <br>
	 * 验证日期格式是否有效 
	 * @param stringDate 字符型日期
	 * @param partternDttmType 匹配的日期格式
	 * @return 返回true/false
	 */
	public static boolean isValidDate(String stringDate, String partternDttmType) {	
		if(stringDate.length()!=partternDttmType.length()){
			return false;
		}
		
		SimpleDateFormat sdf = new SimpleDateFormat(partternDttmType);
		try {
			sdf.setLenient(false);
			sdf.parse(stringDate);
			return true;
		} catch (ParseException e) {
			return false;
		}
	}
	
	/**
	 * Description: <br>
	 * 将转入的日期按传入的格式进行格式化 
	 * @param date 待格式化的日期
	 * @param dateType 格式化模板
	 * @return 格式化之后的日期字符串
	 */
	public static String formatDate(Date date, String dateType) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateType);
		sdf.setLenient(false);
		return sdf.format(date);
	}
	
	/**
	 * Description: <br>
	 * 将转入的字符串日期按传入的格式进行格式化 
	 * @param date 原来日期字符串
	 * @param oldType 原来日期格式
	 * @param newType 新的日期格式
	 * @return 格式化之后的日期字符串
	 * @throws ParseException
	 */
	public static String formatDate(String date,String oldType,String newType) throws ParseException  {
		SimpleDateFormat oldSDF = new SimpleDateFormat(oldType);	
		oldSDF.setLenient(false);			
		Date d = oldSDF.parse(date);
		
		SimpleDateFormat newSDF = new SimpleDateFormat(newType);	
		newSDF.setLenient(false);
		
		return newSDF.format(d);
	}
	
	/**
	 * Description: <br>
	 * 将传入的字符串日期传为java.util.Date.
	 * @param dateString
	 * @return java.util.Date 对象(yyyy-MM-dd)
	 */
	public static Date formatDate(String dateString,String stringType) {
		DateFormat format = new SimpleDateFormat(stringType); 
		Date date = null; 
		try { 
			format.setLenient(false);
            date = format.parse(dateString);  
        } catch (ParseException e) {
            e.printStackTrace(); 
        } 
		return date;
	}
	
	/**
	 * Description: <br>
	 * 计算所传进去的参数yyyy,mm,dd是一年当中第几个星期?
	 * @param yyyy int类型(年)
	 * @param mm int类型(月)
	 * @param dd int类型(日)
	 * @return int类型(第几个星期)
	 */
	public static int whichWeekInYear(int yyyy,int mm,int dd){
		Calendar cal=Calendar.getInstance();
		cal.set(Calendar.YEAR, yyyy);
		cal.set(Calendar.MONTH, mm);
		cal.set(Calendar.DAY_OF_MONTH, dd);
		int weekno=cal.get(Calendar.WEEK_OF_YEAR);	
		return weekno;
	}
	
	/**
	 * Description: <br>
	 * 计算一年中的第几星期是几号?
	 * @param year int类型(年)
	 * @param weekOfYear int类型(一年中的第几个星期)
	 * @return dttm String类型(日期yyyy-MM-dd)
	 */
	public static String whichDayInYearMonth(int year,int weekOfYear){
		SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
		df.setLenient(false);
		Calendar cal=Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.WEEK_OF_YEAR, weekOfYear);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		String str = df.format(cal.getTime());
		
		return str;
	}
	
	/**
	 * Description: <br>
	 * 精确计算相隔天数的方法
	 * @param startDttm Calendar类型(起始时间)
	 * @param endDttm Calendar类型(结束时间)
	 * @return days int类型(天数)
	 */
	public static int getDaysBetween (Calendar startDttm, Calendar endDttm){
        if (startDttm.after(endDttm)){ 
            java.util.Calendar swap = startDttm;
            startDttm = endDttm;
            endDttm = swap;
        }
        int days = endDttm.get(Calendar.DAY_OF_YEAR) - startDttm.get(Calendar.DAY_OF_YEAR);
        int y2 = endDttm.get(Calendar.YEAR);
        if (startDttm.get(Calendar.YEAR) != y2){
            startDttm = (Calendar) startDttm.clone();
            do{
                days += startDttm.getActualMaximum(Calendar.DAY_OF_YEAR);//得到当年的实际天数
                startDttm.add(Calendar.YEAR, 1);
            } while (startDttm.get(Calendar.YEAR) != y2);
        }
        return days;
    }
	
	/**
	 * Description: <br>
	 * 获取多少年前/后的今天
	 * @param years 多少年：（正数：往后多少年；负数：往前多少年）
	 * @type 格式
	 * @return 多少年前/后的今天
	 */
	public static String getTodayWithYear(int years,String type){
		SimpleDateFormat dft = new SimpleDateFormat(type);
		dft.setLenient(false);
		Date today = new Date();		
		Calendar date = Calendar.getInstance();		
		date.setTime(today);		
		date.set(Calendar.YEAR, date.get(Calendar.YEAR) + years);		
		return dft.format(date.getTime());
	}
	
	/**
	 * Description: <br>
	 * 返回当前时间的String类型
	 * @param type 格式化参数（如：yyyy-MM-dd、yyyy-MM-dd HH:mm:ss）
	 * @return 返回格式化后的字符串
	 */
	public static String getSysDate(String type) {
		SimpleDateFormat sf = new SimpleDateFormat(type);
		sf.setLenient(false);
		Date sysNow = new Date();
		String nowDttm = sf.format(sysNow);
		return nowDttm;
	}
	
	/**
	 * Description: <br>
	 * 返回当前时间的java.util.Date类型
	 * @return 返回当前时间（new Date()）
	 */
	public static Date getSysDate() {
		return new Date();
	}
	
	/**
	 * Description: <br>
	 * 返回昨天的java.util.Date类型
	 * @return 返回昨天的当前时间
	 */
	public static Date getSysLastDate() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DAY_OF_MONTH, -1);
		return c.getTime(); 
	}
	
	/**
	 * Description: <br>
	 * 返回昨天的java.util.Date类型
	 * @return 返回当个月当前时间
	 */
	public static Date getSysLastMonth() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, -1);
		return c.getTime(); 
	}
	
	/**
	 * Description: <br>
	 * 返回昨天的java.util.Date类型
	 * @return 返回上个月的某一天
	 */
	public static Date getSysLastMonthAnyDate(int dateOfLastMonth) {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, -1);//今天的时间月份-1支持1月的上月
		c.set(Calendar.DAY_OF_MONTH, dateOfLastMonth);//设置上月几号
		return c.getTime(); 
	}
	
	/**
	 * Description: <br>
	 * 将一个毫秒值转换成小时:分钟:秒返回
	 * @param millisecond 毫秒值
	 * @return 小时:分钟:秒,毫秒
	 */
	public static String formatMillisecond2hms(Long millisecond){
		StringBuilder  sb = new StringBuilder(); 
		int hour = 0; 
		int minute = 0; 
		int second = 0; 
		//second = millisecond.intValue()/1000;
		
		if(millisecond > 1000){
			second = millisecond.intValue()/1000;
			millisecond = millisecond % 1000; 
		}
		
		if (second > 60) { 
			minute = second / 60; 
			second = second % 60; 
		}
		if (minute > 60) { 
			hour = minute / 60; 
			minute = minute % 60; 
		}
		sb.append(String.valueOf(hour));
		sb.append(":");
		sb.append(String.valueOf(minute));
		sb.append(":");
		sb.append(String.valueOf(second));
		sb.append(",");
		sb.append(String.valueOf(millisecond));
		return  sb.toString();
	}
	
	/**
	 * Description: <br>
	 * 根据日期获取秒
	 * @param date 日期
	 * @return 秒
	 */
	public static String getSeconds(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);	
		return StringUtils.formatInt2String(calendar.get(Calendar.SECOND), 2, EDirection.LEFT, ZERO);
	}
	
	/**
	 * Description: <br>
	 * 根据日期获取分钟
	 * @param date 日期
	 * @return 分钟
	 */
	public static String getMinutes(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		
		return StringUtils.formatInt2String(calendar.get(Calendar.MINUTE), 2, EDirection.LEFT, ZERO);
	}
	
	/**
	 * Description: <br>
	 * 根据日期获取时
	 * @param date 日期
	 * @return 小时
	 */
	public static String getHours(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		
		return StringUtils.formatInt2String(calendar.get(Calendar.HOUR_OF_DAY), 2, EDirection.LEFT, ZERO);
	}
	
	/**
	 * Description: <br>
	 * 根据日期获取日
	 * @param date 日期
	 * @return 日
	 */
	public static String getDate(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		
		return StringUtils.formatInt2String(calendar.get(Calendar.DAY_OF_MONTH), 2, EDirection.LEFT, ZERO);
	}
	
	/**
	 * Description: <br>
	 * 根据日期获取星期
	 * @param date 日期
	 * @return 日
	 */
	public static int getWeeks(Date date){		
		final int dayNames[] = {7,1,2,3,4,5,6};
        Calendar calendar = Calendar.getInstance();        
        calendar.setTime(date);
        
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        return dayNames[dayOfWeek - 1];
	}
	
	/** 
	 * Description: <br>
	 * 根据日期获取月
	 * @param date 日期
	 * @return 月
	 */
	public static int getMonths(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		
		return calendar.get(Calendar.MONTH)+1;
	}
	
	/**
	 * Description: <br>
	 * 根据日期获取年
	 * @param date 日期
	 * @param lastTwo 是否取年份的最后两位
	 * @return 年
	 */
	public static String getYear(Date date,boolean lastTwo){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		String tmp = StringUtils.formatInt2String(calendar.get(Calendar.YEAR), 4,EDirection.LEFT, ZERO);
		return lastTwo?tmp.substring(2):tmp;
	}
}


